﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Longbow.Config;
using System.Reflection;

using Longbow.Service;

namespace Longbow
{

	public enum ModuleType : int
	{
		AssemblyModule = 1,
		NativeModule = 2,
		Sl2RemoteModule
	}

	public class Platform
	{


		//public delegate bool OnModuleLoad(string fileName, ModuleType moduleType);

		private IConfig config = null;

		private IServiceManager serviceManager = null;


		private ModuleManager moduleManager = new ModuleManager();


		static Platform()
		{

		}

		public Platform()
		{
		}


		public void Initialize()
		{
			serviceManager = new ServiceManagerImpl();
			ServiceProxy.Initialize(serviceManager);
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="config"></param>
		public void Load(IConfig config)
		{
			if (!config.Loaded)
			{
				config.Load();
			}
			this.config = config;

			string[] paths = null;

			paths = config.GetModulePaths(ModuleType.AssemblyModule);
			foreach (string path in paths)
			{
				string[] fileNames = config.GetModuleFileNames(path, ModuleType.AssemblyModule);
				LoadAssemblyModules(fileNames);
			}

			paths = config.GetModulePaths(ModuleType.NativeModule);
			foreach (string path in paths)
			{
				string[] fileNames = config.GetModuleFileNames(path, ModuleType.NativeModule);
				LoadNativeModules(fileNames);
			}

		}

		private void LoadAssemblyModules(string[] fileNames)
		{
			foreach (string fileName in fileNames)
			{
				LoadAssemblyModule(fileName);
			}
		}

		private void LoadAssemblyModule(string fileName)
		{
			string loadPolicy = config.GetModuleProperty(fileName, "load.policy");

			// If the module not need to load immediately, create a module ref object.
			IModuleRef moduleRef = new AssemblyModuleRef(fileName);
			if (!loadPolicy.Equals("LoadNow"))
			{
				

			}
			else
			{
				// Load now
				if (moduleRef.Load())
				{
					// Load successful
				}
			}
		}


		private void LoadNativeModules(string[] fileNames)
		{
			foreach (string fileName in fileNames)
			{
				LoadNativeModule(fileName);
			}
		}

		private void LoadNativeModule(string fileName)
		{
			string loadPolicy = config.GetModuleProperty(fileName, "load.policy");

			// If the module not need to load immediately, create a module ref object.
			IModuleRef moduleRef = new NativeModuleRef(fileName);
			if (!loadPolicy.Equals("LoadNow"))
			{


			}
			else
			{
				// Load now
				// TODO: Load DLLs using P/Invoke. 
				if (moduleRef.Load())
				{
					// Load successful
				}
			}
		}


		public IConfig GetConfig()
		{
			return this.config;
		}






	}
}
